package com.example.logs.server;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

/**
 * 用于记录天网日志
 * 使用文件收集方式记录日志，需要在项目中定义好slf4j的相关桥接模块（如logback或者log4j、log4j2）
 *
 * @author John
 * @since 2020/05/26
 */
public class BusinessUtils {
    private final static Logger log = LoggerFactory.getLogger(BusinessUtils.class);
    private final static Gson GSON = new GsonBuilder().disableHtmlEscaping().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
    private static String IP;

    static {
        try {
            IP = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            log.error("获取本机IP失败", e);
            IP = "UNKNOW";
        }
    }
    //region printInfo


    /**
     * 记录天网日志Info信息
     *
     * @param msg         消息体
     * @param module      模块
     * @param category    大类
     * @param subcategory 小类
     * @param filter1     过滤文本1
     * @param filter2     过滤文本2
     * @param ex          输出的堆栈信息
     */
    public static void printInfo(String msg, LogModuleEnum module, LogCategoryEnum category,
                                 LogSubCategoryEnum subcategory, String filter1, String filter2, Throwable ex) {
        log.info(getRecodeMsg(msg, module, category, subcategory, filter1, filter2), ex);
    }

    /**
     * 记录天网日志Info信息
     *
     * @param msg         消息体
     * @param module      模块
     * @param category    大类
     * @param subcategory 小类
     * @param filter1     过滤文本1
     * @param filter2     过滤文本2
     */
    public static void printInfo(String msg, LogModuleEnum module, LogCategoryEnum category,
                                 LogSubCategoryEnum subcategory, String filter1, String filter2) {
        printInfo(msg, module, category, subcategory, filter1, filter2, null);
    }

    /**
     * 记录天网日志Info信息（简化版，带ex）
     *
     * @param msg     消息体
     * @param module  模块
     * @param filter1 过滤文本1
     * @param filter2 过滤文本2
     * @param ex      输出的堆栈信息
     */
    public static void printInfo(String msg, LogModuleEnum module, String filter1, String filter2, Throwable ex) {
        printInfo(msg, module, null, null, filter1, filter2, ex);
    }

    /**
     * 记录天网日志Info信息（简化版）
     *
     * @param msg     消息体
     * @param module  模块
     * @param filter1 过滤文本1
     * @param filter2 过滤文本2
     */
    public static void printInfo(String msg, LogModuleEnum module, String filter1, String filter2) {
        printInfo(msg, module, null, null, filter1, filter2, null);
    }
    //endregion

    //region printError

    /**
     * 记录天网日志Error信息
     *
     * @param msg         消息体
     * @param module      模块
     * @param category    大类
     * @param subcategory 小类
     * @param filter1     过滤文本1
     * @param filter2     过滤文本2
     * @param ex          输出的堆栈信息
     */
    public static void printError(String msg, LogModuleEnum module, LogCategoryEnum category,
                                  LogSubCategoryEnum subcategory, String filter1, String filter2, Throwable ex) {

        //记录日志
        log.error(getRecodeMsg(msg, module, category, subcategory, filter1, filter2), ex);
    }

    /**
     * 记录天网日志Error信息（简化版）
     *
     * @param msg     消息体
     * @param module  模块
     * @param filter1 过滤文本1
     * @param filter2 过滤文本2
     * @param ex      输出的堆栈信息
     */
    public static void printError(String msg, LogModuleEnum module, String filter1, String filter2, Throwable ex) {
        printError(msg, module, null, null, filter1, filter2, ex);
    }
    //endregion

    //region printWarn

    /**
     * 记录天网日志Warn信息（简化版,不带ex）
     *
     * @param msg     消息体
     * @param module  模块
     * @param filter1 过滤文本1
     * @param filter2 过滤文本2
     */
    public static void printWarn(String msg, LogModuleEnum module, String filter1, String filter2) {
        printWarn(msg, module, null, null, filter1, filter2, null);
    }

    /**
     * 记录天网日志Warn信息（简化版）
     *
     * @param msg     消息体
     * @param module  模块
     * @param filter1 过滤文本1
     * @param filter2 过滤文本2
     * @param ex      输出的堆栈信息
     */
    public static void printWarn(String msg, LogModuleEnum module, String filter1, String filter2, Throwable ex) {
        printWarn(msg, module, null, null, filter1, filter2, ex);
    }

    /**
     * 记录天网日志Warn信息（不带ex）
     *
     * @param msg         消息体
     * @param module      模块
     * @param category    大类
     * @param subcategory 小类
     * @param filter1     过滤文本1
     * @param filter2     过滤文本2
     */
    public static void printWarn(String msg, LogModuleEnum module, LogCategoryEnum category,
                                 LogSubCategoryEnum subcategory, String filter1, String filter2) {
        printWarn(msg, module, category, subcategory, filter1, filter2, null);
    }


    /**
     * 记录天网日志Warn信息
     *
     * @param msg         消息体
     * @param module      模块
     * @param category    大类
     * @param subcategory 小类
     * @param filter1     过滤文本1
     * @param filter2     过滤文本2
     * @param ex          输出的堆栈信息
     */
    public static void printWarn(String msg, LogModuleEnum module, LogCategoryEnum category,
                                 LogSubCategoryEnum subcategory, String filter1, String filter2, Throwable ex) {
        log.warn(getRecodeMsg(msg, module, category, subcategory, filter1, filter2), ex);
    }

    //endregion

    //region printDebug

    /**
     * 记录天网日志Debug信息（简化版,不带ex）
     *
     * @param msg     消息体
     * @param module  模块
     * @param filter1 过滤文本1
     * @param filter2 过滤文本2
     */
    public static void printDebug(String msg, LogModuleEnum module, String filter1, String filter2) {
        printDebug(msg, module, null, null, filter1, filter2, null);
    }

    /**
     * 记录天网日志Debug信息（简化版）
     *
     * @param msg     消息体
     * @param module  模块
     * @param filter1 过滤文本1
     * @param filter2 过滤文本2
     * @param ex      输出的堆栈信息
     */
    public static void printDebug(String msg, LogModuleEnum module, String filter1, String filter2, Throwable ex) {
        printDebug(msg, module, null, null, filter1, filter2, ex);
    }

    /**
     * 记录天网日志Debug信息（不带ex）
     *
     * @param msg         消息体
     * @param module      模块
     * @param category    大类
     * @param subcategory 小类
     * @param filter1     过滤文本1
     * @param filter2     过滤文本2
     */
    public static void printDebug(String msg, LogModuleEnum module, LogCategoryEnum category,
                                  LogSubCategoryEnum subcategory, String filter1, String filter2) {
        printDebug(msg, module, category, subcategory, filter1, filter2, null);
    }


    /**
     * 记录天网日志Debug信息
     * 注意：如果需要输出debug信息，需要在日志记录组件中开启debug级别的日志记录
     *
     * @param msg         消息体
     * @param module      模块
     * @param category    大类
     * @param subcategory 小类
     * @param filter1     过滤文本1
     * @param filter2     过滤文本2
     * @param ex          输出的堆栈信息
     */
    public static void printDebug(String msg, LogModuleEnum module, LogCategoryEnum category,
                                  LogSubCategoryEnum subcategory, String filter1, String filter2, Throwable ex) {
        log.debug(getRecodeMsg(msg, module, category, subcategory, filter1, filter2), ex);
    }

    //endregion


    /**
     * 用于对各个天网日志记录方法的入参进行校验和修正，组成msg字段所需信息
     *
     * @param msg         消息体
     * @param module      模块
     * @param category    大类
     * @param subcategory 小类
     * @param filter1     过滤文本1
     * @param filter2     过滤文本2
     * @return 将所有字段经过去null转换后整理出的msg返回
     */
    private static String getRecodeMsg(String msg, LogModuleEnum module, LogCategoryEnum category,
                                       LogSubCategoryEnum subcategory, String filter1, String filter2) {
        if (module != null) {
            MDC.put("MODULE", module.getCode());
        } else {
            MDC.remove("MODULE");
        }
        if (category != null) {
            MDC.put("CATEGORY", category.getCode());
        } else {
            MDC.remove("CATEGORY");
        }
        if (subcategory != null) {
            MDC.put("SUB_CATEGORY", subcategory.getCode());
        } else {
            MDC.remove("SUB_CATEGORY");
        }
        if (filter1 != null) {
            MDC.put("FILTER1", filter1);
        } else {
            MDC.remove("FILTER1");
        }
        if (filter2 != null) {
            MDC.put("FILTER2", filter2);
        } else {
            MDC.remove("FILTER2");
        }
        MDC.put("IP", IP);
        return msg;

    }

}
